package com.xiaodu.acer.phoneplay.widget;

import android.content.Context;

import com.jakewharton.rxbinding2.view.RxView;
import com.orhanobut.logger.Logger;
import com.xiaodu.acer.phoneplay.R;
import com.xiaodu.acer.phoneplay.bean.AppDownloadInfo;
import com.xiaodu.acer.phoneplay.bean.AppInfo;
import com.xiaodu.acer.phoneplay.common.Constant;
import com.xiaodu.acer.phoneplay.common.rx.RxHttpReponseCompat;
import com.xiaodu.acer.phoneplay.common.rx.subscriber.RxSchedulers;
import com.xiaodu.acer.phoneplay.common.util.AppUtils;
import com.xiaodu.acer.phoneplay.common.util.PermissionUtil;

import java.io.File;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import library.base.BaseBean;
import library.util.ACache;
import retrofit2.http.GET;
import retrofit2.http.Path;
import zlc.season.rxdownload2.RxDownload;
import zlc.season.rxdownload2.entity.DownloadBean;
import zlc.season.rxdownload2.entity.DownloadEvent;
import zlc.season.rxdownload2.entity.DownloadFlag;
import zlc.season.rxdownload2.entity.DownloadRecord;

import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

public class DownloadButtonConntroller {


    private RxDownload mRxDownload;

    private Api mApi;

    public DownloadButtonConntroller(RxDownload download) {
        this.mRxDownload = download;

        if (mRxDownload != null) {
            mApi = mRxDownload.getRetrofit().create(Api.class);
        }
    }


    /**
     * 真正的开始下载
     *
     * @param url
     * @return
     */
    private Observable<DownloadEvent> receiveDownladStatus(String url) {
        return mRxDownload.receiveDownloadStatus(url);
    }

    /**
     * 给AppInfo赋值
     *
     * @param bean
     * @return
     */
    public AppInfo downloadRecord2AppInfo(DownloadRecord bean) {
        AppInfo info = new AppInfo();

        info.setId(Integer.parseInt(bean.getExtra1()));
        info.setIcon(bean.getExtra2());
        info.setDisplayName(bean.getExtra3());
        info.setPackageName(bean.getExtra4());
        info.setReleaseKeyHash(bean.getExtra5());

        AppDownloadInfo downloadInfo = new AppDownloadInfo();
        downloadInfo.setDowanloadUrl(bean.getUrl());
        info.setAppDownloadInfo(downloadInfo);
        Logger.e(bean.getUrl());
        return info;
    }


    private DownloadBean appInfo2DownloadBean(AppInfo info) {
        DownloadBean downloadBean = new DownloadBean();
        downloadBean.setUrl(info.getAppDownloadInfo().getDownloadUrl());
        downloadBean.setSaveName(info.getReleaseKeyHash() + ".apk");

        downloadBean.setExtra1(info.getId() + "");
        downloadBean.setExtra2(info.getIcon());
        downloadBean.setExtra3(info.getDisplayName());
        downloadBean.setExtra4(info.getPackageName());
        downloadBean.setExtra5(info.getReleaseKeyHash());

        return downloadBean;
    }


    /**
     * 外界去调用，下载的功能
     *
     * @param btn
     * @param record
     */
    public void handClick(final DownloadProgressButton btn, DownloadRecord record) {
        AppInfo info = downloadRecord2AppInfo(record);
//        Logger.e(record.getUrl());
        receiveDownladStatus(record.getUrl())
                .subscribe(new DownloadConsumer(btn, info));
        // handClick(btn, info);

    }

    public void handClick(final DownloadProgressButton btn, final AppInfo appInfo) {
        if (mApi == null) {
            return;
        }
        isAppInstalled(btn.getContext(), appInfo)
                .flatMap(new Function<DownloadEvent, ObservableSource<DownloadEvent>>() {
                    @Override
                    public ObservableSource<DownloadEvent> apply(DownloadEvent downloadEvent) throws Exception {
                        //如果没有安装，那么检测apk文件是否存在
                        if (DownloadFlag.UN_INSTALL == downloadEvent.getFlag()) {
                            return isApkFileExsit(btn.getContext(), appInfo);
                        } else {
                            return Observable.just(downloadEvent);
                        }
                    }
                })
                .flatMap(new Function<DownloadEvent, ObservableSource<DownloadEvent>>() {
                    @Override
                    public ObservableSource<DownloadEvent> apply(DownloadEvent downloadEvent) throws Exception {
                        // TODO: 2018/1/18  如果文件存在，返回下载的状态或是开始下载
                        Logger.e("下载状态：+" + downloadEvent.getFlag());
                        if (DownloadFlag.FILE_EXIST == downloadEvent.getFlag()) {
                            return getAppDownloadInfo(appInfo)
                                    .flatMap(new Function<AppDownloadInfo, ObservableSource<DownloadEvent>>() {
                                        @Override
                                        public ObservableSource<DownloadEvent> apply(AppDownloadInfo appDownloadInfo) throws Exception {
                                            appInfo.setAppDownloadInfo(appDownloadInfo);
                                            return receiveDownloadStatus(appDownloadInfo.getDownloadUrl());
                                        }
                                    });
                        }
                        return Observable.just(downloadEvent);
                    }
                })
                .compose(RxSchedulers.<DownloadEvent>io_main())
                .subscribe(new DownloadConsumer(btn, appInfo));

    }

    /**
     * 检测apk是否已经安装
     *
     * @param context
     * @param info
     * @return
     */
    public Observable<DownloadEvent> isAppInstalled(Context context, AppInfo info) {
        DownloadEvent event = new DownloadEvent();
        event.setFlag(AppUtils.isInstalled(context,
                info.getPackageName()) ? DownloadFlag.INSTALLED : DownloadFlag.UN_INSTALL);
        return Observable.just(event);

    }


    /**
     * 检测apk是否下载
     *
     * @param context
     * @param appInfo
     * @return
     */
    public Observable<DownloadEvent> isApkFileExsit(Context context, AppInfo appInfo) {

        String path = ACache.get(context).getAsString(Constant.APK_DOWNLOAD_DIR)
                + File.separator + appInfo.getReleaseKeyHash();
        File file = new File(path);

        DownloadEvent event = new DownloadEvent();
        //文件存在还是未下载
        event.setFlag(file.exists() ? DownloadFlag.FILE_EXIST : DownloadFlag.NORMAL);

        return Observable.just(event);
    }


    /**
     * 如果没有下载，开始下载
     *
     * @param appInfo
     * @return
     */
    public Observable<AppDownloadInfo> getAppDownloadInfo(AppInfo appInfo) {
        return mApi.getAppDownloadInfo(appInfo.getId())
                .compose(RxHttpReponseCompat.<AppDownloadInfo>compatResult());
    }

    /**
     * 返回下载的状态
     *
     * @param downloadUrl
     * @return
     */
    private ObservableSource<DownloadEvent> receiveDownloadStatus(String downloadUrl) {
        return mRxDownload.receiveDownloadStatus(downloadUrl);
    }

    private void receiveDownloadStatusTemp(String downloadUrl) {
        mRxDownload.receiveDownloadStatus(downloadUrl);
    }


    /**
     * 传到这里的返回值
     */
    class DownloadConsumer implements Consumer<DownloadEvent> {

        DownloadProgressButton btn;

        AppInfo mAppInfo;

        public DownloadConsumer(DownloadProgressButton btn, AppInfo appInfo) {
            this.btn = btn;
            mAppInfo = appInfo;
        }

        @Override
        public void accept(DownloadEvent event) throws Exception {
            int flag = event.getFlag();
            btn.setTag(R.id.tag_apk_flag, flag);
            bindClick(btn, mAppInfo);

            switch (flag) {
                case DownloadFlag.INSTALLED:
                    btn.setText("运行");
                    break;
                case DownloadFlag.NORMAL:
                    btn.download();
                    break;
                case DownloadFlag.STARTED:
                    //Logger.e("下载进度" + (int) event.getDownloadStatus().getPercentNumber());
                    btn.setProgress((int) event.getDownloadStatus().getPercentNumber());
                    break;
                case DownloadFlag.PAUSED:
                    //  Logger.e("下载进度" + (int) event.getDownloadStatus().getPercentNumber());
                    btn.setProgress((int) event.getDownloadStatus().getPercentNumber());
                    btn.paused();
                    break;
                case DownloadFlag.WAITING:
                    btn.setText("等待中");

                case DownloadFlag.COMPLETED:    //已完成
                    btn.setText("安装");
                    break;
                case DownloadFlag.FAILED:   //下载失败
                    btn.setText("失败");
                    break;
                case DownloadFlag.DELETED:  //已删除

                    break;
                default:

                    break;
            }
        }


    }

    private void bindClick(final DownloadProgressButton btn, final AppInfo appInfo) {
        RxView.clicks(btn)
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) {
                        int flag = (int) btn.getTag(R.id.tag_apk_flag);
                        Logger.e(flag + "=======" + o.toString());
                        Logger.e(appInfo.toString());
                        switch (flag) {
                            case DownloadFlag.INSTALLED:    //已经安装，但未使用的
                                Logger.e("runApp");
                                runApp(btn.getContext(), appInfo.getPackageName());
                                break;
                            case DownloadFlag.STARTED:  //已开始下载状态暂停下载
                                try {
                                    Logger.e(appInfo.getAppDownloadInfo().getDownloadUrl());
                                    pauseDownload(appInfo.getAppDownloadInfo().getDownloadUrl());
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                Logger.e("暂停");
                                break;
                            case DownloadFlag.NORMAL://没下载或者暂停状态开始下载
                            case DownloadFlag.PAUSED:
                                startDownload(btn, appInfo);

                                break;
                            case DownloadFlag.COMPLETED:    //完成下载
                                try {
                                    Logger.e("安装");
                                    installApp(btn.getContext(), appInfo);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                break;
                            default:
                                Logger.e("default");
                                break;
                        }
                    }

                });
    }

    private void runApp(Context context, String packageName) {
        AppUtils.runApp(context, packageName);
    }

    /**
     * 暂停下载
     */
    private void pauseDownload(String url) {
        mRxDownload.pauseServiceDownload(url).subscribe();
    }

    /**
     * 开始下载
     *
     * @param btn
     * @param appInfo
     */
    private void startDownload(final DownloadProgressButton btn, final AppInfo appInfo) {
        PermissionUtil.requestPermisson
                (btn.getContext(), WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            final AppDownloadInfo downloadInfo = appInfo.getAppDownloadInfo();

                            if (downloadInfo == null) {
                                getAppDownloadInfo(appInfo).subscribe(new Consumer<AppDownloadInfo>() {
                                    @Override
                                    public void accept(@NonNull AppDownloadInfo appDownloadInfo) throws Exception {
                                        appInfo.setAppDownloadInfo(appDownloadInfo);
                                        download(btn, appInfo);
                                    }
                                });
                            } else {
                                download(btn, appInfo);
                            }
                        }
                    }
                });
    }

    private void download(DownloadProgressButton btn, AppInfo appInfo) {
        mRxDownload.serviceDownload(appInfo2DownloadBean(appInfo))
                .subscribe();
        mRxDownload.receiveDownloadStatus
                (appInfo.getAppDownloadInfo().getDownloadUrl())
                .subscribe(new DownloadConsumer(btn, appInfo));

        Logger.e(appInfo.getAppDownloadInfo().getDownloadUrl());
    }

    //安装app
    private void installApp(Context context, AppInfo appInfo) {
        //设置安装路径
        String path = ACache.get(context).getAsString(Constant.APK_DOWNLOAD_DIR
                + File.separator + appInfo.getReleaseKeyHash());
        AppUtils.installApk(context, path);
        //  PackageUtils.install(context, path);
    }


    interface Api {
        @GET("download/{id}")
        Observable<BaseBean<AppDownloadInfo>> getAppDownloadInfo(@Path("id") int id);
    }
}
